﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using GEF2.Model.Storage;
using GEF2.Model;
//using GEF2.View;

namespace GEF2
{

    public partial class MainWindow : Form
    {
        Point mSelectStart;
        bool mMouseDown;

        public MainWindow()
        {
            InitializeComponent();
            mMouseDown = false;
        }

        public void DrawEntity(Entity entity)
        {
            using (System.Drawing.Graphics canvas = this.CreateGraphics())
            {
                entity.draw(canvas);
            }
        }

        #region Request add entity
        public event EventHandler AddEntity;
        protected virtual void OnAddEntity(EventArgs args)
        {
            if (AddEntity != null) AddEntity(this, args);
        }
        #endregion

        #region Delete entity
        public event EventHandler DeleteEntity;
        protected virtual void OnDeleteEntity(EventArgs args)
        {
            if (DeleteEntity != null) DeleteEntity(this, args);
        }
        #endregion

        private void MainWindow_MouseDown(object sender, MouseEventArgs e)
        {
            mSelectStart = e.Location;
            mMouseDown = true;
            if (cbxNew.Checked)
            {
                OnAddEntity(new LocationEventArgs(e.Location));
            }

            if (cbxSelect.Checked || cbxConnect.Checked)
            {
                EntityProxy entityProxy = (EntityProxy)ApplicationFacade.Instance.RetrieveProxy(EntityProxy.NAME);
                SearchProxy searchProxy = (SearchProxy)ApplicationFacade.Instance.RetrieveProxy(SearchProxy.NAME);
                List<Entity> list = searchProxy.searchByPoint(e.Location);
                foreach (Entity entity in entityProxy.Entitys)
                {
                    bool selected = list.IndexOf(entity) >= 0;
                    using (System.Drawing.Graphics canvas = this.CreateGraphics())
                    {
                        this.Invalidate(entity.boundingBox());
                        entity.select(canvas, selected);
                    }
                }
            }


            if (cbxDelete.Checked)
            {
                SearchProxy searchProxy = (SearchProxy)ApplicationFacade.Instance.RetrieveProxy(SearchProxy.NAME);
                List<Entity> list = searchProxy.searchByPoint(e.Location);
                foreach (Entity entity in list)
                {
                    OnDeleteEntity(new DeleteEntityEventArgs(entity));
                }
            }
        }

        private void MainWindow_MouseMove(object sender, MouseEventArgs e)
        {
            if (cbxSelect.Checked)
            {
                if (mMouseDown)
                {
                    System.Drawing.Rectangle rect = new System.Drawing.Rectangle(Math.Min(mSelectStart.X, e.Location.X), Math.Min(mSelectStart.Y, e.Location.Y), Math.Max(mSelectStart.X, e.Location.X), Math.Max(mSelectStart.Y, e.Location.Y));
                    EntityProxy entityProxy = (EntityProxy)ApplicationFacade.Instance.RetrieveProxy(EntityProxy.NAME);
                    SearchProxy searchProxy = (SearchProxy)ApplicationFacade.Instance.RetrieveProxy(SearchProxy.NAME);
                    List<Entity> list = searchProxy.searchByRect(rect);
                    foreach (Entity entity in entityProxy.Entitys)
                    {
                        bool selected = list.IndexOf(entity) >= 0;
                        using (System.Drawing.Graphics canvas = this.CreateGraphics())
                        {
                            this.Invalidate(entity.boundingBox());
                            entity.select(canvas, selected);
                        }
                    }
                }
            }

            if (cbxConnect.Checked)
            {
                this.Invalidate();
                this.Update();
                if (mMouseDown)
                {
                    using (System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Black, 5))
                    {
                        using (System.Drawing.Graphics graph = this.CreateGraphics())
                        {
                            graph.DrawLine(pen, mSelectStart, e.Location);
                        }
                    }
                }
            }
        }

        private void MainWindow_MouseUp(object sender, MouseEventArgs e)
        {
            if (cbxConnect.Checked)
            {
                // Connect both entity's
                SearchProxy searchProxy = (SearchProxy)ApplicationFacade.Instance.RetrieveProxy(SearchProxy.NAME);
                var start = searchProxy.searchByPoint(mSelectStart);
                if (start.Count() > 0)
                {
                    var end = searchProxy.searchByPoint(e.Location);
                    if (end.Count() > 0)
                    {
                        if (start[0] != end[0])
                        {
                            MessageBox.Show("Connect!");
                        }
                    }
                }
            }
            mMouseDown = false;
        }

        private void MainWindow_Paint(object sender, PaintEventArgs e)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(() => { MainWindow_Paint(sender, e); }));
            }
            else
            {
                var rect = e.ClipRectangle;

                SearchProxy searchProxy = (SearchProxy)ApplicationFacade.Instance.RetrieveProxy(SearchProxy.NAME);
                List<Entity> list = searchProxy.searchByRect(rect);

                foreach (Entity entity in list)
                {
                    using (System.Drawing.Graphics canvas = this.CreateGraphics())
                    {
                        entity.draw(canvas);
                    }
                }
            }
        }

        public ListBox EntityListWindow()
        {
            return lstEntitys;
        }

        public void ChangeTool()
        {
            mMouseDown = false;
        }

        private void cbxNew_CheckedChanged(object sender, EventArgs e)
        {
            ChangeTool();
        }

        private void cbxSelect_CheckedChanged(object sender, EventArgs e)
        {
            ChangeTool();
        }

        private void cbxConnect_CheckedChanged(object sender, EventArgs e)
        {
            ChangeTool();
        }

        private void cbxDelete_CheckedChanged(object sender, EventArgs e)
        {
            ChangeTool();
        }

    }
	    public class LocationEventArgs : EventArgs
        {
            public LocationEventArgs(Point point)
            {
                Location = point;
            }
            public Point Location { get; set; }
        }

        public class DeleteEntityEventArgs : EventArgs
        {
            public DeleteEntityEventArgs(Entity entity)
            {
                Entity = entity;
            }
            public Entity Entity { get; set; }
        }

}
